/* MIT License
 *
 * Copyright (c) 1998 Massachusetts Institute of Technology
 * Copyright (c) 2004 Daniel Stenberg
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 * SPDX-License-Identifier: MIT
 */
#ifndef HEADER_CARES_IPHLPAPI_H
#define HEADER_CARES_IPHLPAPI_H

#if defined(USE_WINSOCK)

#  ifndef INET_ADDRSTRLEN
#    define INET_ADDRSTRLEN 22
#  endif

#  ifndef INET6_ADDRSTRLEN
#    define INET6_ADDRSTRLEN 65
#  endif

/* ---------------------------------- */
#  if !defined(_WS2DEF_) && !defined(__CSADDR_DEFINED__) && \
    !defined(__CSADDR_T_DEFINED)
/* ---------------------------------- */

typedef struct _SOCKET_ADDRESS {
  LPSOCKADDR lpSockaddr;
  INT        iSockaddrLength;
} SOCKET_ADDRESS, *PSOCKET_ADDRESS;

typedef struct _CSADDR_INFO {
  SOCKET_ADDRESS LocalAddr;
  SOCKET_ADDRESS RemoteAddr;
  INT            iSocketType;
  INT            iProtocol;
} CSADDR_INFO, *PCSADDR_INFO;

/* --------------------------------- */
#  endif /* ! _WS2DEF_           && \  */
/*        ! __CSADDR_DEFINED__ && \  */
/*        ! __CSADDR_T_DEFINED       */
/* --------------------------------- */

/* ------------------------------- */
#  if !defined(IP_ADAPTER_DDNS_ENABLED)
/* ------------------------------- */

#    define IP_ADAPTER_ADDRESS_DNS_ELIGIBLE 0x0001
#    define IP_ADAPTER_ADDRESS_TRANSIENT    0x0002

#    define IP_ADAPTER_DDNS_ENABLED               0x0001
#    define IP_ADAPTER_REGISTER_ADAPTER_SUFFIX    0x0002
#    define IP_ADAPTER_DHCP_ENABLED               0x0004
#    define IP_ADAPTER_RECEIVE_ONLY               0x0008
#    define IP_ADAPTER_NO_MULTICAST               0x0010
#    define IP_ADAPTER_IPV6_OTHER_STATEFUL_CONFIG 0x0020

#    define GAA_FLAG_SKIP_UNICAST       0x0001
#    define GAA_FLAG_SKIP_ANYCAST       0x0002
#    define GAA_FLAG_SKIP_MULTICAST     0x0004
#    define GAA_FLAG_SKIP_DNS_SERVER    0x0008
#    define GAA_FLAG_INCLUDE_PREFIX     0x0010
#    define GAA_FLAG_SKIP_FRIENDLY_NAME 0x0020

typedef enum {
  IpPrefixOriginOther = 0,
  IpPrefixOriginManual,
  IpPrefixOriginWellKnown,
  IpPrefixOriginDhcp,
  IpPrefixOriginRouterAdvertisement
} IP_PREFIX_ORIGIN;

typedef enum {
  IpSuffixOriginOther = 0,
  IpSuffixOriginManual,
  IpSuffixOriginWellKnown,
  IpSuffixOriginDhcp,
  IpSuffixOriginLinkLayerAddress,
  IpSuffixOriginRandom
} IP_SUFFIX_ORIGIN;

typedef enum {
  IpDadStateInvalid = 0,
  IpDadStateTentative,
  IpDadStateDuplicate,
  IpDadStateDeprecated,
  IpDadStatePreferred
} IP_DAD_STATE;

typedef enum {
  IfOperStatusUp = 1,
  IfOperStatusDown,
  IfOperStatusTesting,
  IfOperStatusUnknown,
  IfOperStatusDormant,
  IfOperStatusNotPresent,
  IfOperStatusLowerLayerDown
} IF_OPER_STATUS;

typedef enum {
  ScopeLevelInterface    = 0x0001,
  ScopeLevelLink         = 0x0002,
  ScopeLevelSubnet       = 0x0003,
  ScopeLevelAdmin        = 0x0004,
  ScopeLevelSite         = 0x0005,
  ScopeLevelOrganization = 0x0008,
  ScopeLevelGlobal       = 0x000E
} SCOPE_LEVEL;

typedef struct _IP_ADAPTER_UNICAST_ADDRESS {
  union {
    ULONGLONG Alignment;

    struct {
      ULONG Length;
      DWORD Flags;
    } s;
  } u;
  struct _IP_ADAPTER_UNICAST_ADDRESS *Next;
  SOCKET_ADDRESS                      Address;
  IP_PREFIX_ORIGIN                    PrefixOrigin;
  IP_SUFFIX_ORIGIN                    SuffixOrigin;
  IP_DAD_STATE                        DadState;
  ULONG                               ValidLifetime;
  ULONG                               PreferredLifetime;
  ULONG                               LeaseLifetime;
} IP_ADAPTER_UNICAST_ADDRESS, *PIP_ADAPTER_UNICAST_ADDRESS;

typedef struct _IP_ADAPTER_ANYCAST_ADDRESS {
  union {
    ULONGLONG Alignment;

    struct {
      ULONG Length;
      DWORD Flags;
    } s;
  } u;
  struct _IP_ADAPTER_ANYCAST_ADDRESS *Next;
  SOCKET_ADDRESS                      Address;
} IP_ADAPTER_ANYCAST_ADDRESS, *PIP_ADAPTER_ANYCAST_ADDRESS;

typedef struct _IP_ADAPTER_MULTICAST_ADDRESS {
  union {
    ULONGLONG Alignment;

    struct {
      ULONG Length;
      DWORD Flags;
    } s;
  } u;
  struct _IP_ADAPTER_MULTICAST_ADDRESS *Next;
  SOCKET_ADDRESS                        Address;
} IP_ADAPTER_MULTICAST_ADDRESS, *PIP_ADAPTER_MULTICAST_ADDRESS;

typedef struct _IP_ADAPTER_DNS_SERVER_ADDRESS {
  union {
    ULONGLONG Alignment;

    struct {
      ULONG Length;
      DWORD Reserved;
    } s;
  } u;
  struct _IP_ADAPTER_DNS_SERVER_ADDRESS *Next;
  SOCKET_ADDRESS                         Address;
} IP_ADAPTER_DNS_SERVER_ADDRESS, *PIP_ADAPTER_DNS_SERVER_ADDRESS;

typedef struct _IP_ADAPTER_PREFIX {
  union {
    ULONGLONG Alignment;

    struct {
      ULONG Length;
      DWORD Flags;
    } s;
  } u;
  struct _IP_ADAPTER_PREFIX *Next;
  SOCKET_ADDRESS             Address;
  ULONG                      PrefixLength;
} IP_ADAPTER_PREFIX, *PIP_ADAPTER_PREFIX;

typedef struct _IP_ADAPTER_ADDRESSES {
  union {
    ULONGLONG Alignment;

    struct {
      ULONG Length;
      DWORD IfIndex;
    } s;
  } u;
  struct _IP_ADAPTER_ADDRESSES  *Next;
  PCHAR                          AdapterName;
  PIP_ADAPTER_UNICAST_ADDRESS    FirstUnicastAddress;
  PIP_ADAPTER_ANYCAST_ADDRESS    FirstAnycastAddress;
  PIP_ADAPTER_MULTICAST_ADDRESS  FirstMulticastAddress;
  PIP_ADAPTER_DNS_SERVER_ADDRESS FirstDnsServerAddress;
  PWCHAR                         DnsSuffix;
  PWCHAR                         Description;
  PWCHAR                         FriendlyName;
  BYTE                           PhysicalAddress[MAX_ADAPTER_ADDRESS_LENGTH];
  DWORD                          PhysicalAddressLength;
  DWORD                          Flags;
  DWORD                          Mtu;
  DWORD                          IfType;
  IF_OPER_STATUS                 OperStatus;
  DWORD                          Ipv6IfIndex;
  DWORD                          ZoneIndices[16];
  PIP_ADAPTER_PREFIX             FirstPrefix;
} IP_ADAPTER_ADDRESSES, *PIP_ADAPTER_ADDRESSES;

/* -------------------------------- */
#  endif /* ! IP_ADAPTER_DDNS_ENABLED */
/* -------------------------------- */

#endif /* USE_WINSOCK */

#endif /* HEADER_CARES_IPHLPAPI_H */
